//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Eic.h"
#include "CtrlStd.h" //Pour RafraichirFondSansObligatoire
#include "MTAG_CtrlStd.h"
#include "CRichEdit.h"

#define MODULE_TAG MTAG_CRICHEDIT


#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck est utilisé est utilisé pour être sûr que les composants créés n'ont
// aucune fonction virtuelle pure.
//

static inline void ValidCtrCheck(CRichEdit *)
{
   new CRichEdit(NULL);
}

/*******************************************************************************
void __fastcall ConvertirTexteSimpleVersRichEdit(const AnsiString &aTexte, CRichedit *RichEdit)

Fonction : Permet de remplir un RichEdit avec du texte comprenant un formatage basique.
           Les régles de formatage sont le suivantes :
              - Italique : Tout texte encadré par '#i' (Ex : Mot en #iItalique#i)
              - Gras : Tout texte encadré par '#b'
              - Souligné : Tout texte encadré par '#u'

Paramètres d'entrée : aTexte : Texte formaté basiquement

Paramètres de sortie : RichEdit remplit correctement
*******************************************************************************/
void __fastcall ConvertirTexteSimpleVersRichEdit(const AnsiString &aTexte, TRichEdit2 *RichEdit)
{
int iDebItalique = -1;
int iDebGras     = -1;
int iDebSouligne = -1;
TRichEdit2 *RichEditTmp = NULL;
TStringStream *ssTexte = NULL;
int i = 1;
char cCarSelect;
try
   {
   //On utilise un RichEdit temporaire pour que le traitement effectué sur la chaîne ne soit pas visible à l'écran
   RichEditTmp = new TRichEdit2((TComponent*)NULL);
   RichEditTmp->Font = RichEdit->Font;
   RichEditTmp->Parent = RichEdit->Parent;
   RichEditTmp->Visible = false;
   RichEditTmp->Lines->Text = aTexte;

   while((i = RichEditTmp->FindText("#", i-1, RichEditTmp->Text.Length()-1, TSearchTypes()<< stMatchCase)+1) != 0)
      {
      RichEditTmp->SelStart = i; // (On enlève car base 0)
      RichEditTmp->SelLength = 1;
      cCarSelect = RichEditTmp->SelText[1];

      //SI nous sommes sur deux marqueurs consécutifs (##), ce n'est pas un marqueur, l'utilisateur veut afficher un dièse
      if (cCarSelect == '#')
         {
         //On supprime l'un des deux marqueur
         RichEditTmp->SelStart = i-1; // (On enlève car base 0)
         RichEditTmp->SelLength = 1;
         RichEditTmp->SelText = EmptyStr;
         i++; //Et on passe sur le caractère qui suit les marqueurs
         }
      //SI nous sommes sur un marqueur qui est suivi d'un caractère
      else
         {
         i++; //On passe sur le caractère définissant le type de marqueur

         RichEditTmp->SelStart = i-1; // (On enlève car base 0)
         RichEditTmp->SelLength = 1;
         cCarSelect = RichEditTmp->SelText[1];

         if (cCarSelect == 'i')
            {
            if (iDebItalique == -1)
               iDebItalique = i-1;
            else
               {
               RichEditTmp->SelStart = iDebItalique-1; // (On enlève car base 0)
               RichEditTmp->SelLength = i - iDebItalique;
               RichEditTmp->SelAttributes->AddStyle(fsItalic);

               //Suppression du marqueur définissant la fin de la zone Italique
               RichEditTmp->SelStart = i-1-1; // (On enlève car base 0)
               RichEditTmp->SelLength = 2;
               RichEditTmp->SelText = EmptyStr;

               //Suppression du marqueur définissant le début de la zone Italique
               RichEditTmp->SelStart = iDebItalique-1; // (On enlève car base 0)
               RichEditTmp->SelLength = 2;
               RichEditTmp->SelText = EmptyStr;

               if (iDebGras > iDebItalique)     //On replace l'indice s'il est après les caractères qui viennent d'être supprimé
                  iDebGras -= 2;
               if (iDebSouligne > iDebItalique) //On replace l'indice s'il est après les caractères qui viennent d'être supprimé
                  iDebSouligne -= 2;

               i -= 4; //On a supprimé 4 caractères => on replace l'indice correctement

               iDebItalique = -1;
               }
            }
         else if (cCarSelect == 'b')
            {
            if (iDebGras == -1)
               iDebGras = i-1;
            else
               {
               RichEditTmp->SelStart = iDebGras-1; // (On enlève car base 0)
               RichEditTmp->SelLength = i - iDebGras;
               RichEditTmp->SelAttributes->AddStyle(fsBold);

               RichEditTmp->SelStart = 0; // (On enlève car base 0)
               RichEditTmp->SelLength = i-1-1-1;

               //Suppression du marqueur définissant la fin de la zone Grasse
               RichEditTmp->SelStart = i-1-1; // (On enlève car base 0)
               RichEditTmp->SelLength = 2;
               RichEditTmp->SelText = EmptyStr;

               //Suppression du marqueur définissant le début de la zone Grasse
               RichEditTmp->SelStart = iDebGras-1; // (On enlève car base 0)
               RichEditTmp->SelLength = 2;
               RichEditTmp->SelText = EmptyStr;

               if (iDebItalique > iDebGras) //On replace l'indice s'il est après les caractères qui viennent d'être supprimé
                  iDebItalique -= 2;
               if (iDebSouligne > iDebGras) //On replace l'indice s'il est après les caractères qui viennent d'être supprimé
                  iDebSouligne -= 2;

               i -= 4; //On a supprimé 4 caractères => on replace l'indice correctement

               iDebGras = -1;
               }
            }
         else if (cCarSelect == 'u')
            {
            if (iDebSouligne == -1)
               iDebSouligne = i-1;
            else
               {
               RichEditTmp->SelStart = iDebSouligne-1; // (On enlève car base 0)
               RichEditTmp->SelLength = i - iDebSouligne;
               RichEditTmp->SelAttributes->AddStyle(fsUnderline);

               //Suppression du marqueur définissant la fin de la zone soulignée
               RichEditTmp->SelStart = i-1-1; // (On enlève car base 0)
               RichEditTmp->SelLength = 2;
               RichEditTmp->SelText = EmptyStr;

               //Suppression du marqueur définissant le début de la zone soulignée
               RichEditTmp->SelStart = iDebSouligne-1; // (On enlève car base 0)
               RichEditTmp->SelLength = 2;
               RichEditTmp->SelText = EmptyStr;

               if (iDebItalique > iDebSouligne)     //On replace l'indice s'il est après les caractères qui viennent d'être supprimé
                  iDebItalique -= 2;
               if (iDebGras > iDebSouligne) //On replace l'indice s'il est après les caractères qui viennent d'être supprimé
                  iDebGras -= 2;

               i -= 4; //On a supprimé 4 caractères => on replace l'indice correctement

               iDebSouligne = -1;
               }
            }
         }
      i++;
      }


   // On affecte le RichEdit traité dans le RichEdit final.
   ssTexte = new TStringStream(EmptyStr);
   RichEditTmp->Lines->SaveToStream(ssTexte);
   ssTexte->Position = 0;
   RichEdit->Lines->LoadFromStream(ssTexte);
   delete ssTexte; ssTexte = NULL;
   }
catch(Exception &e)
   {
   EICDisplayException(TAG(0), e);
   }
}

//---------------------------------------------------------------------------
__fastcall CRichEdit::CRichEdit(TComponent* Owner)
   : TRichEdit2(Owner)
{
m_Ole = NULL;
m_SveWindowProc = WindowProc;
WindowProc = MyWndProc;

Font->Name = "Arial"; //Par défaut c'est MS Sans Serif
Font->Size = 9; //Par défaut c'est 8

}

__fastcall CRichEdit::~CRichEdit()
{
try
   {
   }
catch(Exception &e)
   {
   EICDisplayException(TAG(20), e);
   }
}

/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres de sortie :

Valeur retournée :
*******************************************************************************/
void __fastcall CRichEdit::MyWndProc(Messages::TMessage &Message)
{
try
   {
   if(Message.Msg == WM_CREATE)
      {
      if(!ComponentState.Contains(csDesigning))
         //On active les objets OLE
         m_Ole     = new TIRichEditOle(this);
      }
   else if(Message.Msg == WM_DESTROY)
      {
      if(!ComponentState.Contains(csDesigning))
         if (m_Ole)
            {
            delete m_Ole;
            m_Ole = NULL;
            }
      }
  }
catch(Exception &e)
   {
   EICDisplayException(TAG(380), e);
   }
  m_SveWindowProc(Message);
}

/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres de sortie :

Valeur retournée :
*******************************************************************************/
void __fastcall CRichEdit::SetEnabled(bool bEnabled)
{
inherited::Enabled = bEnabled;
RafraichirFondSansObligatoire(this);
}

/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres de sortie :

Valeur retournée :
*******************************************************************************/
bool __fastcall CRichEdit::GetEnabled()
{
return inherited::Enabled;
}

/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres de sortie :

Valeur retournée :
*******************************************************************************/
void __fastcall CRichEdit::SetReadOnly(bool bReadOnly)
{
inherited::ReadOnly = bReadOnly;
RafraichirFondSansObligatoire(this);
}

/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres de sortie :

Valeur retournée :
*******************************************************************************/
bool __fastcall CRichEdit::GetReadOnly() 
{
return inherited::ReadOnly;
}
//---------------------------------------------------------------------------
namespace Crichedit
{
   void __fastcall PACKAGE Register()
   {
       TComponentClass classes[1] = {__classid(CRichEdit)};
       RegisterComponents("EIC Ctrlstd", classes, 0);
   }
}
//---------------------------------------------------------------------------
 
